Skip to content

feat(logger): new stack_trace field with rich exception details #3147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Oct 10, 2023

Conversation

stevrobu
Copy link
Contributor

@stevrobu stevrobu commented Sep 28, 2023

Issue number: #1268

Summary

Changes

Added environment variable and formatter constructor parameter to allow users to include additional JSON formatted full stack trace to their logger.exception output.

To test the change, the following Lambda code will enable the enhanced stacktrace and log the exception along with the stacktrace:

import requests

from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.typing import LambdaContext

ENDPOINT = "http://httpbin.org/status/500"
logger = Logger(serialize_stacktrace=True)


def lambda_handler(event: dict, context: LambdaContext) -> str:
    try:
        ret = requests.get(ENDPOINT)
        ret.raise_for_status()
    except requests.HTTPError as e:
        logger.exception(e)
        raise RuntimeError("Unable to fullfil request") from e

    return "hello world"

Response in CloudWatch logs should be:

{
   "level":"ERROR",
   "location":"lambda_handler:16",
   "message":"500 Server Error: INTERNAL SERVER ERROR for url: http://httpbin.org/status/500",
   "timestamp":"2023-10-09 17:47:50,191+0000",
   "service":"service_undefined",
   "exception":"Traceback (most recent call last):\n  File \"/var/task/app.py\", line 14, in lambda_handler\n    ret.raise_for_status()\n  File \"/var/task/requests/models.py\", line 1021, in raise_for_status\n    raise HTTPError(http_error_msg, response=self)\nrequests.exceptions.HTTPError: 500 Server Error: INTERNAL SERVER ERROR for url: http://httpbin.org/status/500",
   "exception_name":"HTTPError",
   "stack_trace":{
      "type":"HTTPError",
      "value":"500 Server Error: INTERNAL SERVER ERROR for url: http://httpbin.org/status/500",
      "module":"requests.exceptions",
      "frames":[
         {
            "file":"/var/task/app.py",
            "line":14,
            "function":"lambda_handler",
            "statement":"ret.raise_for_status()"
         },
         {
            "file":"/var/task/requests/models.py",
            "line":1021,
            "function":"raise_for_status",
            "statement":"raise HTTPError(http_error_msg, response=self)"
         }
      ]
   }
}

User experience

User can now parse JSON stacktraces instead of string stacktraces.

Checklist

If your change doesn't seem to apply, please leave them unchecked.

Is this a breaking change?

Not a breaking change.

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@stevrobu stevrobu requested a review from a team September 28, 2023 20:18
@pull-request-size pull-request-size bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Sep 28, 2023
@boring-cyborg
Copy link

boring-cyborg bot commented Sep 28, 2023

Thanks a lot for your first contribution! Please check out our contributing guidelines and don't hesitate to ask whatever you need.
In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link

@boring-cyborg boring-cyborg bot added documentation Improvements or additions to documentation tests labels Sep 29, 2023
@pull-request-size pull-request-size bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Sep 29, 2023
@leandrodamascena leandrodamascena linked an issue Oct 2, 2023 that may be closed by this pull request
2 tasks
@leandrodamascena leandrodamascena changed the title feat(logger): Parse exceptions into structured logs feat(logger): add structured exception logging in JSON format Oct 2, 2023
Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @stevrobu! Thanks for submitting this PR, this is an amazing first contribution! We need to change a few things before merging this.

One thing I'm missing is the include_stacktrace parameter in the Logger instance. I see you added it in PowertoolsFormatter, but I think we can improve the user experience by adding the Logger class in the same way. You can keep this parameter in PowertoolsFormatter because someone can use the Formatter class in some special cases, but adding this in the Logger class improves the experience.

from aws_lambda_powertools import Logger

logger = Logger(include_stacktrace=True)

@stevrobu
Copy link
Contributor Author

stevrobu commented Oct 3, 2023

@leandrodamascena : I will add the parameter to the logger as you suggested. It actually already works that way because any of the kwargs from the Logger class initialization are passed to the formatter in the structure_logs method. I actually didn't realize this until I wrote a test prior to making the update and the test passed.

I've updated the tests so that the linter does not complain and I'm checking out the other suggestions.

@leandrodamascena
Copy link
Contributor

@leandrodamascena : I will add the parameter to the logger as you suggested. It actually already works that way because any of the kwargs from the Logger class initialization are passed to the formatter in the structure_logs method. I actually didn't realize this until I wrote a test prior to making the update and the test passed.

I've updated the tests so that the linter does not complain and I'm checking out the other suggestions.

Hi @stevrobu! I think you need to push your local commits, right? I can't see the new code.

@stevrobu
Copy link
Contributor Author

stevrobu commented Oct 3, 2023 via email

@leandrodamascena
Copy link
Contributor

I have not finished yet. I should be able to push tomorrow.

Aaa, sorry for my mistake. I saw you resolve conversations and assumed you made the commits. No rush, take your time.

@boring-cyborg boring-cyborg bot added the internal Maintenance changes label Oct 6, 2023
@stevrobu
Copy link
Contributor Author

stevrobu commented Oct 6, 2023

@leandrodamascena - I have checked in the latest updates. Thanks for the feedback!

@codecov-commenter
Copy link

codecov-commenter commented Oct 9, 2023

Codecov Report

All modified lines are covered by tests ✅

Comparison is base (e72fbbe) 95.95% compared to head (8c1831e) 95.96%.
Report is 6 commits behind head on develop.

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #3147   +/-   ##
========================================
  Coverage    95.95%   95.96%           
========================================
  Files          195      195           
  Lines         8364     8381   +17     
  Branches      1559     1562    +3     
========================================
+ Hits          8026     8043   +17     
  Misses         276      276           
  Partials        62       62           
Files Coverage Δ
aws_lambda_powertools/logging/formatter.py 100.00% <100.00%> (ø)
aws_lambda_powertools/logging/logger.py 99.45% <ø> (ø)
aws_lambda_powertools/logging/types.py 100.00% <100.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @heitorlessa can you pls review this PR?

For me, it is approved! Amazing work @stevrobu! 🚀

@rubenfonseca rubenfonseca self-requested a review October 10, 2023 09:29
@rubenfonseca
Copy link
Contributor

Looking at this now

Copy link
Contributor

@rubenfonseca rubenfonseca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments and questions, but overall looks good!

rubenfonseca
rubenfonseca previously approved these changes Oct 10, 2023
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@heitorlessa heitorlessa changed the title feat(logger): add structured exception logging in JSON format feat(logger): new stack_trace field with rich exception details Oct 10, 2023
@leandrodamascena leandrodamascena self-requested a review October 10, 2023 11:47
@leandrodamascena leandrodamascena merged commit e555df1 into aws-powertools:develop Oct 10, 2023
@boring-cyborg
Copy link

boring-cyborg bot commented Oct 10, 2023

Awesome work, congrats on your first merged pull request and thank you for helping improve everyone's experience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commons documentation Improvements or additions to documentation internal Maintenance changes logger size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Parse exceptions into structured logs
6 participants